package com.ruoyi.web.controller.yn;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.yn.domain.*;
import com.ruoyi.yn.service.*;
import com.ruoyi.yn.vo.YnUserAddressVo;
import com.ruoyi.yn.vo.YnUserOrderVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author Ming
 * @since 2023-04-23 15:48:57
 */
@Api(tags = "微信小程序登录及个人信息")
@RestController
@AllArgsConstructor
@Slf4j
@RequestMapping("/wx/user/")
public class WxMaUserController {


    private final IYnWxUserService ynWxUserService;

    private final IYnUserAddressService ynUserAddressService;

    private final IYnUserOrderService ynUserOrderService;

    private final IYnRecyclingTypeService recyclingTypeService;

    private final IYnRecyclingWeightService recyclingWeightService;

    /**
     * 登陆接口
     */
    @ApiOperation("微信小程序用户登录并获取个人信息")
    @GetMapping("login")
    public R<YnWxUser> login(@RequestParam("code") String code,@RequestParam("encryptedData") String encryptedData,@RequestParam("ivStr") String ivStr) {
        if (StringUtils.isBlank(code)) {
            return R.fail("empty jscode");
        }
        YnWxUser userInfo = ynWxUserService.userLogin(code,encryptedData,ivStr);
        return R.ok(userInfo);
    }

    /**
     * 添加用户地址
     */
    @ApiOperation("添加用户地址")
    @PostMapping("addAddress")
    public R<String> addAddress(@RequestBody YnUserAddressVo ynUserAddressVo) {
        ynUserAddressVo.setId(null);
        ynUserAddressService.save(ynUserAddressVo);
        return R.ok();
    }

    /**
     * 更新用户地址
     */
    @ApiOperation("更新用户地址")
    @PostMapping("updateAddress")
    public R<String> updateAddress(@RequestBody YnUserAddressVo ynUserAddressVo) {
        ynUserAddressService.updateById(ynUserAddressVo);
        return R.ok();
    }

    /**
     * 用户地址列表
     */
    @ApiOperation("用户地址列表")
    @GetMapping("addressList")
    public R<List<YnUserAddress>> addressList(@RequestParam("wxUserId")String wxUserId) {
        List<YnUserAddress> ynUserAddresses = ynUserAddressService.lambdaQuery().eq(YnUserAddress::getWxUserId, wxUserId)
                .eq(YnUserAddress::getIsDelete,"0")
                .orderByDesc(YnUserAddress::getCreateTime).list();
        return R.ok(ynUserAddresses);
    }

    /**
     * 删除用户地址
     */
    @ApiOperation("删除用户地址")
    @GetMapping("deleteAddress")
    public R<String> deleteAddress(@RequestParam("id")String id) {
        ynUserAddressService.lambdaUpdate().eq(YnUserAddress::getId,id).set(YnUserAddress::getIsDelete,"1").update();
        return R.ok();
    }

    /**
     * 用户订单列表
     */
    @ApiOperation("用户订单列表-分页")
    @GetMapping("orderList}")
    public R<Page<YnUserOrderVo>> orderList(
            @ApiParam("用户ID") @RequestParam("wxUserId") String wxUserId,
            @ApiParam("第几页") @RequestParam("current") Long current,
            @ApiParam("每页条数") @RequestParam("size") Long size,
            @ApiParam("订单状态:0待处理1已处理2已取消3已评价") @RequestParam(value = "state",required = false) String state
    ) {
        Page<YnUserOrder> page = ynUserOrderService.lambdaQuery().eq(ObjectUtil.isNotEmpty(state), YnUserOrder::getState, state)
                .eq(YnUserOrder::getWxUserId, wxUserId).page(new Page<>(current, size));
        Page<YnUserOrderVo> resultPage = new Page<>();
        resultPage.setTotal(page.getTotal());
        resultPage.setCurrent(page.getCurrent());
        resultPage.setSize(page.getSize());
        List<YnUserOrder> records = page.getRecords();
        Map<String, String> typeMap = recyclingTypeService.list().stream().collect(Collectors.toMap(YnRecyclingType::getId, YnRecyclingType::getName));
        Map<String, String> weightMap = recyclingWeightService.list().stream().collect(Collectors.toMap(YnRecyclingWeight::getId, YnRecyclingWeight::getWeight));
        Map<String,YnUserAddress> ynUserAddresses = ynUserAddressService.lambdaQuery().eq(YnUserAddress::getWxUserId, wxUserId).list()
                .stream().collect(Collectors.toMap(YnUserAddress::getId, Function.identity()));
        List<YnUserOrderVo> ynUserOrderVos = records.stream().map(o -> {
            YnUserOrderVo userOrderVo = BeanUtil.toBean(o, YnUserOrderVo.class);
            String typeNames = Arrays.stream(userOrderVo.getRecyclingTypeIds().split(",")).map(typeMap::get).collect(Collectors.joining(","));
            userOrderVo.setRecyclingTypeNames(typeNames);
            userOrderVo.setRecyclingWeightName(weightMap.get(userOrderVo.getRecyclingWeightId()));
            userOrderVo.setYnUserAddress(ynUserAddresses.get(userOrderVo.getUserAddressId()));
            return userOrderVo;
        }).collect(Collectors.toList());
        resultPage.setRecords(ynUserOrderVos);
        return R.ok(resultPage);
    }

    @ApiOperation("创建订单")
    @PostMapping("createOrder")
    public R<String> createOrder(@RequestBody YnUserOrder ynUserOrder) {
        // 若未指定回收员，则系统匹配一个距离最近的回收员
        if (ObjectUtil.isEmpty(ynUserOrder.getRecyclerId())) {
            String recyclerId = ynUserOrderService.recentRecyclers(ynUserOrder.getUserAddressId());
            ynUserOrder.setRecyclerId(recyclerId);
        }
        boolean success = ynUserOrderService.save(ynUserOrder);
        return success ? R.ok() : R.fail();
    }

    @ApiOperation("编辑订单")
    @PostMapping("updateOrder")
    public R<String> updateOrder(@RequestBody YnUserOrder ynUserOrder) {
        YnUserOrder order = ynUserOrderService.getById(ynUserOrder.getId());
        if (ObjectUtil.isEmpty(order)) {
            return R.fail("订单不存在");
        }
        if (order.getState().equals("1")) {
            return R.fail("订单已处理，不允许修改");
        }
        boolean success = ynUserOrderService.updateById(ynUserOrder);
        return success ? R.ok() : R.fail();
    }


}
